home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Taifun
/
Taifun 048 (1988-02-15)(Ossowski, Stefan)(DE)(PD).zip
/
Taifun 048 (1988-02-15)(Ossowski, Stefan)(DE)(PD).adf
/
Mandel
/
source
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-01-23
|
24KB
|
886 lines
#define DEBUG
/* :ts=4
* M A N D E L B R O T C O N S T R U C T I O N S E T
*
* Main Program, including some general routines
*/
#include <exec/types.h>
#include <intuition/intuition.h>
/* #include <graphics/display.h> */
#ifdef DEBUG
# include <stdio.h>
# undef STATIC
# define STATIC /* EMPTY */
#endif
#include "mandel.h"
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct LayersBase *LayersBase;
struct TextAttr Topaz80 = {
(STRPTR) "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
struct TextAttr Topaz60 = {
(STRPTR) "topaz.font", TOPAZ_SIXTY, FS_NORMAL, FPF_ROMFONT };
struct NewScreen MandelNScreen =
{
0, 0, 320, 256, /* LeftEdge, TopEdge, Width, Height */
4, /* Depth */
2, 1, /* DetailPen, BlockPen */
NULL, /* viewmode LORES */
CUSTOMSCREEN, /* type */
&Topaz80, /* Font (default) */
(UBYTE *)"Mandelbrot Construction Set V1.0" /* DefaultTitle for menubar */
};
struct NewWindow MainNWindow =
{
0, 0, 0, 0, /* LeftEdge, TopEdge, Width, Height */
2, 1, /* DetailPen, BlockPen */
CLOSEWINDOW | MENUPICK | MOUSEBUTTONS | SIZEVERIFY |
MENUVERIFY,
WINDOWCLOSE | ACTIVATE | WINDOWSIZING | WINDOWDRAG |
WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH | GIMMEZEROZERO,
NULL, /* FirstGadget */
NULL, /* default CheckMark */
(UBYTE *) "Mandelbrot Construction Window", /* Title */
NULL, /* Screen */
NULL, /* BitMap */
60, 25, /* MinWidth, MinHeight */
-1, -1, /* MaxWidth, MaxHeight */
CUSTOMSCREEN /* Screen type */
};
struct BorderInfo borderinfo;
struct IntuiText PositiveText =
{ AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
AUTOLEFTEDGE, AUTOTOPEDGE, NULL, (UBYTE *) "Continue", NULL },
NegativeText =
{ AUTOFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
AUTOLEFTEDGE, AUTOTOPEDGE, &Topaz60, (UBYTE *) "Cancel", NULL };
STATIC SHORT XY1[] = { 0,0, 0,13, 78,13, 78,0, 0,0 };
STATIC SHORT XY2[] = { 0,0, 0,17, 82,17, 82,0, 0,0 };
STATIC struct Border border[] = {
{ 0, 0, 2,0, JAM1, 5, XY1, &border[1] },
{ -2, -2, 3,0, JAM1, 5, XY2, NULL }
};
struct Gadget NegativeGadget = {
NULL, -100, -20, 79, 14, /* next, LTWH */
GADGHCOMP | GRELBOTTOM | GRELRIGHT,
RELVERIFY | ENDGADGET,
BOOLGADGET | REQGADGET,
(APTR) &border[0], NULL,
&NegativeText, 0, NULL,
NEGGADGETID, NULL };
struct Gadget PositiveGadget = {
&NegativeGadget, 20, -20, 79, 14, /* next, LTWH */
GADGHCOMP | GRELBOTTOM,
RELVERIFY | ENDGADGET,
BOOLGADGET | REQGADGET,
(APTR) &border[0], NULL,
&PositiveText, 0, NULL,
POSGADGETID, NULL };
USHORT ColorMap[MAXDEPTH];
bool ColorMapValid = FALSE;
UBYTE PenTable[MAXDEPTH];
unsigned PenTableMode = MODULO;
short RangeWidth = 2;
struct Screen *MandelScreen = NULL; /* Pointer for OpenScreen return value */
struct Window *MainWindow = NULL; /* Idem for OpenWindow */
void (*WritePixelDepth)() = ZQuadMinC;
double LeftEdge = -0.800, /* Left edge of the picture */
RightEdge = 2.100,
TopEdge = 1.200,
BottomEdge = -1.200;
double CXStep, /* Stepsize through the complex plane */
CYStep;
int PixelStep=1, /* Stepsize on the screen*/
MaxDepth=100; /* Maximum iteration count */
NumColors; /* Number of colors on the screen */
unsigned short FrameX1, FrameX2,
FrameY1, FrameY2;
short MouseStatus = NOTFRAMING;/* Where we are in the process of */
/* selecting a frame */
bool finished = FALSE; /* TRUE to stop the program */
bool Saved = TRUE; /* Indicates the picture has been SAVEd */
bool NameValid = FALSE; /* Indicates the file name is valid */
bool StillDrawing = FALSE; /* Are we still drawing ? */
/* Manx startup stubs, to save some memory. Not useful with Lattice! */
#ifdef MANX_C
_cli_parse() {}
_wb_parse() {}
#endif
/* M A I N E N T R Y P O I N T */
main()
{
register ULONG Class; /* IntuiMessage class */
register USHORT Code; /* and Code field */
struct IntuiMessage *message; /* Expected message pointer */
/* Open each of the libraries and check for a NULL return, which
* indicates unavailability.
*/
IntuitionBase = (struct IntuitionBase *)
OpenLibrary ("intuition.library", LIBRARY_VERSION);
if (IntuitionBase == NULL) MyExit ("Can't open Intuition V1.2 or newer!");
GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", LIBRARY_VERSION);
if (GfxBase == NULL) MyExit ("Can't open Gfx V1.2 or newer!");
LayersBase = (struct LayersBase *)
OpenLibrary("layers.library", LIBRARY_VERSION);
if (LayersBase == NULL) MyExit ("Can't open Layers V1.2 or newer!");
if (InitDisplay((bool)FALSE)) MyExit ("Can't initialise the display properly!");
CalcCSteps();
again:
finished = FALSE;
while (!finished) {
/* Wait for message port to become not empty, and extract the msg */
WaitPort(MainWindow->UserPort);
while ( message = (struct IntuiMessage *)
GetMsg(MainWindow->UserPort) ) {
gotmessage:
Class = message->Class;
Code = message->Code;
if (Class & ~(MOUSEBUTTONS | INTUITICKS)) {
ReplyMsg(message); /* Pointer is not valid anymore */
}
switch (Class) {
case MENUPICK:
GotMenu(Code); break;
case MOUSEBUTTONS:
case INTUITICKS:
CheckMouse(Class, Code, message->MouseX, message->MouseY,
message->Seconds, message->Micros);
ReplyMsg(message);
break;
case SIZEVERIFY:
StopFraming(); /* Fall Through to MenuVerify */
case MENUVERIFY:
break; /* Just make sure there is no half-drawn frame */
case CLOSEWINDOW:
finished = TRUE;
break;
/* default: Ignore strange messages */
} /* End Switch The Class Of The Message */
} /* End While There Is A Message */
} /* End While Not Finished */
/* So we are finished.
* And, by the way, are we SURE we are finished alltogether ??
*/
if (!Sure()) {
backto again;
}
CleanupDisplay((bool)TRUE);
MyExit(NULL); /* Indicate Good Exit */
} /* End of main */
/* Initialize the screen and the windows and the menus */
bool InitDisplay(borderless)
bool borderless;
{
USHORT ViewModes = MandelNScreen.ViewModes;
struct Screen WBScreen;
int i;
StopFraming();
Saved = TRUE; /* We can easily reconstruct this `picture' */
/* Get Left, Top, Width, Height */
GetScreenData(&WBScreen, (long)sizeof(WBScreen),
(long)WBENCHSCREEN, NULL);
MandelNScreen.Width = WBScreen.Width;
MandelNScreen.Height = WBScreen.Height;
/* Maybe we have an interlaced WorkBench screen */
if (WBScreen.ViewPort.Modes & LACE) MandelNScreen.Height >>= 1;
/* And maybe, if we use MWB, it isn't hires... */
if (!(WBScreen.ViewPort.Modes & HIRES)) MandelNScreen.Width <<= 1;
if (ViewModes & LACE) MandelNScreen.Height <<= 1;
if (ViewModes & HIRES) {
MandelNScreen.Depth = 4;
NumColors = 16;
/* Avoid a bug in MrgCop()?? if you have a PAL machine with */
/* a screen wider than 640 taller than 213 and with 4 bitplanes */
if (MandelNScreen.Width > 640)
MandelNScreen.Width = 640;
} else {
MandelNScreen.Depth = 5;
NumColors = 32;
MandelNScreen.Width >>= 1;
}
if ( !MandelScreen && !(MandelScreen = OpenScreen(&MandelNScreen)) ) {
skipto abort;
}
if (ColorMapValid)
LoadRGB4(&MandelScreen->ViewPort, ColorMap, (long) NumColors);
MainNWindow.Screen = MandelScreen;
if (MainNWindow.Height < MainNWindow.MinHeight) {
/* First time we open the window */
MainNWindow.LeftEdge = 0;
MainNWindow.TopEdge = MandelScreen->BarHeight;
MainNWindow.Width = MandelScreen->Width;
MainNWindow.Height = MandelScreen->Height - MainNWindow.TopEdge;
} else {
if (ViewModes & HIRES) {
MainNWindow.LeftEdge <<= 1;
MainNWindow.Width <<= 1;
}
if (ViewModes & LACE) {
MainNWindow.TopEdge <<= 1;
MainNWindow.Height <<= 1;
}
}
/* Check for windows that can't be opened */
if (MainNWindow.LeftEdge + MainNWindow.Width > MandelScreen->Width)
MainNWindow.Width = MandelScreen->Width - MainNWindow.LeftEdge;
if (MainNWindow.TopEdge + MainNWindow.Height > MandelScreen->Height)
MainNWindow.Height = MandelScreen->Height - MainNWindow.TopEdge;
if ( !MainWindow && !(MainWindow = OpenWindow(&MainNWindow)) ) {
skipto abort;
}
SetMenuStrip(MainWindow, MandelMenu);
if (borderless) {
DoBorderless(MainWindow, &borderinfo);
}
InitPenTable();
return FALSE;
abort:
CleanupDisplay((bool) TRUE);
return TRUE;
}
bool CleanupDisplay(everything)
bool everything;
{
bool wasborderless;
int i;
StopDrawing();
StopFraming();
wasborderless = (MainWindow != NULL) &&
((MainWindow->Flags & BORDERLESS) != 0);
if (MainWindow) {
/* Save window appearance for later, in low-res non-lace pixels */
MainNWindow.LeftEdge = MainWindow->LeftEdge;
MainNWindow.TopEdge = MainWindow->TopEdge;
MainNWindow.Width = MainWindow->Width;
MainNWindow.Height = MainWindow->Height;
ClearMenuStrip(MainWindow); /* Remove menu strip */
CloseWindow(MainWindow); /* Finally close it */
MainWindow = NULL;
}
/* Save the colors we may have established with great care */
if (MandelScreen) {
for (i=0; i < NumColors; i++) {
ColorMap[i] = GetRGB4(MandelScreen->ViewPort.ColorMap, i);
}
ColorMapValid = TRUE;
if (MandelScreen->ViewPort.Modes & HIRES) {
MainNWindow.LeftEdge >>= 1;
MainNWindow.Width >>= 1;
}
if (MandelScreen->ViewPort.Modes & LACE) {
MainNWindow.TopEdge >>= 1;
MainNWindow.Height >>= 1;
}
/* Close the screen only if `everything' must be cleaned up */
if (everything) {
CloseScreen(MandelScreen);
MandelScreen = NULL;
}
}
return wasborderless;
}
bool DoBorderless(window, borderinfo)
struct Window *window;
struct BorderInfo *borderinfo;
{
/* Make window borderless */
/* register struct Layer_Info *LayerInfo = &window->WScreen->LayerInfo; */
#define LayerInfo NULL /* Since V1.2 */
register struct Layer *Layer = window->RPort->Layer;
register long movex;
register long movey;
register long sizex;
register long sizey;
bool Success = FALSE;
if (window->Flags & BORDERLESS) return TRUE;
LockLayer(LayerInfo, Layer);
window->Flags |= BORDERLESS;
movex = -window->BorderLeft;
movey = -window->BorderTop;
sizex = window->BorderRight - movex;
sizey = window->BorderBottom - movey;
window->BorderLeft =
window->BorderTop =
window->BorderRight =
window->BorderBottom = 0;
window->GZZWidth += sizex;
window->GZZHeight += sizey;
if ( MoveLayer(LayerInfo, Layer, movex, movey) ) {
Success = SizeLayer(LayerInfo, Layer, sizex, sizey);
if (!Success) {
sizex = sizey = 0;
}
} else {
movex = movey = sizex = sizey = 0;
}
UnlockLayer(Layer);
borderinfo->MoveX = movex;
borderinfo->MoveY = movey;
borderinfo->SizeX = sizex;
borderinfo->SizeY = sizey;
/* Done making borderless */
if (Success) {
return Success;
} else { /* Try to clean up the mess */
UndoBorderless(window, borderinfo);
return FALSE;
}
#undef LayerInfo
}
void UndoBorderless(window, borderinfo)
struct Window *window;
struct BorderInfo *borderinfo;
{
/* ``Another fine mess you got me into!'' (Oliver Hardy) */
/* register struct Layer_Info *LayerInfo = &window->WScreen->LayerInfo; */
#define LayerInfo NULL /* Since V1.2 */
register struct Layer *Layer = window->RPort->Layer;
register long movex = borderinfo->MoveX;
register long movey = borderinfo->MoveY;
register long sizex = borderinfo->SizeX;
register long sizey = borderinfo->SizeY;
bool Success = FALSE;
if (!(window->Flags & BORDERLESS)) return;
LockLayer(LayerInfo, Layer);
SizeLayer(LayerInfo, Layer, -sizex, -sizey);
MoveLayer(LayerInfo, Layer, -movex, -movey);
window->GZZWidth -= sizex;
window->GZZHeight -= sizey;
window->BorderLeft = -movex;
window->BorderTop = -movey;
window->BorderRight = sizex + movex;
window->BorderBottom = sizey + movey;
window->Flags &= ~BORDERLESS;
RefreshWindowFrame(window);
UnlockLayer(Layer);
/* Done Undoing Borderless */
#undef LayerInfo
}
void MyExit(status)
char *status;
{
#ifndef DEBUG2
static char message[] = "\
\0\144\25Mandelbrot Construction Set -- By KosmoSoft Productions\0a\
\0\144\41 \0";
/* 3^5^ 10^ ^ 20^ ^ 30^ ^ 40^ ^ 50^ 55^58^ */
register char *c=message+65;
if (status) {
/* Center the message. Notice `60' is even. */
/* We assume WORD alignment for the string. */
*((WORD *) (message+60)) = 320 - (strlen(status) << 2);
while ((*(c++) = *(status++)) && c < message + 127);
*c = 0;
/* Let's be paranoid for a change... */
if (!IntuitionBase) IntuitionBase = (struct IntuitionBase *)
OpenLibrary ("intuition.library", 0L);
if (IntuitionBase)
DisplayAlert(RECOVERY_ALERT, message, 50L);
else { /* AT_Recovery | AG_OpenLib | AO_Intuition */
CPTR AlertParameter = (CPTR) FindTask(NULL);
Alert(0x00038004L, &AlertParameter);
}
status=1;
}
#else
if (status) {
fprintf(stderr, "Mandelbrot Construction Set Error:\n %s\n",
status);
status = 1;
}
#endif
CleanupDisplay((bool) TRUE);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (LayersBase) CloseLibrary(LayersBase);
if (GfxBase) CloseLibrary(GfxBase);
exit ((int) (status != NULL));
}
bool Sure()
{
bool Result;
ULONG OldIDCMP = MainWindow->IDCMPFlags;
static struct IntuiText Body[] =
{
{ MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
25, 10, NULL, (UBYTE *) "You are going to", &Body[1] },
{ MYFRONTPEN+1, AUTOBACKPEN, AUTODRAWMODE,
57, 25, &Topaz60, (UBYTE *) "destroy", &Body[2] },
{ MYFRONTPEN, AUTOBACKPEN, AUTODRAWMODE,
33, 40, NULL, (UBYTE *) "your picture !", NULL }
};
if (Saved) return TRUE;
ModifyIDCMP(MainWindow, OldIDCMP &~ (MENUVERIFY | SIZEVERIFY | REQVERIFY));
Result = AutoRequest(MainWindow, &Body[0], &PositiveText, &NegativeText,
NULL, NULL, 200L, 90L);
ModifyIDCMP(MainWindow, OldIDCMP);
return Result;
}
/***********************************************************************
* Render a requester in a window. If it won't fit, open a new window.
* This new window will share the IDCMP port with the original
* window. This is to save memory, signal bits and VERIFY deadlocks.
* Returns the window in which the requester actually appears.
*/
struct Window *MyRequest(request, window)
struct Requester *request;
struct Window *window;
{
static struct NewWindow newwindow = {
0, 0, 0, 0, 2, 1,
NULL, /* IDCMP flags -- port shared with main window */
WINDOWDEPTH | WINDOWDRAG | ACTIVATE | SIMPLE_REFRESH | NOCAREREFRESH,
NULL, NULL, NULL, NULL,
NULL, 0, 0, 0, 0, NULL };
int width, height, left, top;
int borderleft, borderright, bordertop, borderbottom;
struct Window *oldwindow = window;
borderleft = window->WScreen->WBorLeft;
borderright = window->WScreen->WBorRight;
bordertop = window->WScreen->BarHeight + 1;
borderbottom = window->WScreen->WBorBottom;
/* Center the requester in the given window.
* If impossible, open a new window to the place the requester in.
*/
width = window->Width - borderleft - borderright;
height = window->Height - bordertop - borderbottom;
left = ((width - request->Width) >> 1) + borderleft;
top = ((height - request->Height) >> 1) + bordertop;
if (width < request->Width || height < request-> Height) {
/* Window too small. Open a new one */
newwindow.Width = request->Width + 2 * borderleft;
newwindow.Height = request->Height + bordertop + borderbottom;
newwindow.LeftEdge = newwindow.TopEdge = 0;
newwindow.Title = window->Title;
newwindow.Screen = window->WScreen;
newwindow.Type = window->WScreen->Flags & SCREENTYPE;
if (window = OpenWindow(&newwindow)) {
window->UserPort = oldwindow->UserPort;
/* Upen up the other port */
ModifyIDCMP(window, GADGETUP);
}
request->LeftEdge = borderleft;
request->TopEdge = bordertop;
} else { /* The requester fits. Center it! */
request->LeftEdge = left;
request->TopEdge = top;
}
if (window && Request(request, window)) return window;
if (window) CloseWindowSafely(window);
return NULL;
}
void EndMyRequest(request, window, original)
struct Requester *request;
struct Window *window, *original;
{
EndRequest(request, window);
if (window != original) CloseWindowSafely(window);
}
/*************************************************************************
* Wait on a request posted by MyRequest.
* Returns when a gadget with GadgetID >= POSGADGETID is released,
* so Gadgets with an ID < POSGADGETID will be ignored.
* Any messages other than GADGETUP will be ignored.
*/
int WaitMyRequest(window)
struct Window *window;
{
int ID = 0;
struct IntuiMessage *message;
struct Gadget *Gadget;
ULONG Class;
ULONG OldIDCMP = window->IDCMPFlags;
if (!window)
return NEGGADGETID;
ModifyIDCMP(window, GADGETUP);
while (ID < POSGADGETID) {
WaitPort(window->UserPort);
while (message = (struct IntuiMessage *) GetMsg(window->UserPort) ) {
Class = message->Class;
Gadget = (struct Gadget *)message->IAddress;
ReplyMsg(message);
if (Class != GADGETUP) continue;
ID = Gadget->GadgetID;
if (ID >= POSGADGETID) break; /* Also gets out of outer loop */
}
}
ModifyIDCMP(window, OldIDCMP);
return ID;
}
void RectDraw(rp, x1, y1, x2, y2)
struct RastPort *rp;
SHORT x1, y1, x2,y2;
{
Move(rp, (long) x1, (long) y1);
Draw(rp, (long) x2, (long) y1);
Draw(rp, (long) x2, (long) y2);
Draw(rp, (long) x1, (long) y2);
if (y2 > y1) y1++; else y1--; /* Don't XOR the first pixel twice */
Draw(rp, (long) x1, (long) y1);
}
void CrossDraw(rp, x, y, left, right, top, bottom)
struct RastPort *rp;
SHORT x, y, top, bottom, left, right;
{
Move(rp, (long) left, (long) y);
Draw(rp, (long) right, (long) y);
Move(rp, (long) x, (long) top);
Draw(rp, (long) x, (long) bottom);
}
void DisableSystemGadgets(gadget)
struct Gadget *gadget;
{
while (gadget) {
if (gadget->GadgetType & SYSGADGET) {
/* Ghost everything except the Title/Dragbar */
if ((gadget->GadgetType & 0x00F0) != WDRAGGING)
OffGadget(gadget, MainWindow, NULL);
gadget->Flags |= GADGDISABLED;
}
gadget = gadget->NextGadget;
}
}
void EnableSystemGadgets(gadget)
struct Gadget *gadget;
{
USHORT Flags = 0;
while (gadget) {
if (gadget->GadgetType & SYSGADGET) {
Flags |= gadget->Flags;
gadget->Flags &= ~GADGDISABLED;
}
gadget = gadget->NextGadget;
}
/* Unghost everthing if necessary */
if (Flags & GADGDISABLED) RefreshWindowFrame(MainWindow);
}
void StopFraming()
{
if (MainWindow) {
EnableSystemGadgets(MainWindow->FirstGadget);
ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags & ~INTUITICKS);
}
MouseStatus = NOTFRAMING;
}
void CheckMouse(Class, Code, MouseX, MouseY, Secs, Micros)
ULONG Class;
USHORT Code;
SHORT MouseX, MouseY;
ULONG Secs, Micros;
{
register SHORT top = MainWindow->BorderTop,
bottom = MainWindow->Height - MainWindow->BorderBottom - 1,
left = MainWindow->BorderLeft,
right = MainWindow->Width - MainWindow->BorderRight - 1;
static ULONG OldSecs, OldMicros;
static SHORT MidX, MidY;
if (StillDrawing || MouseStatus != FLASHING &&
(MouseX < left || MouseX > right || MouseY < top || MouseY > bottom))
return;
MouseX -= left;
MouseY -= top;
if (Class == MOUSEBUTTONS) {
if (Code == SELECTDOWN) {
/* We selected a point */
switch (MouseStatus) {
case NOTFRAMING:
case FLASHING:
MouseStatus = NOPOINT;
DisableSystemGadgets(MainWindow->FirstGadget);
ModifyIDCMP(MainWindow, MainWindow->IDCMPFlags | INTUITICKS);
/* Now we can select our first corner */
break;
case NOPOINT:
FrameX1 = FrameX2 = MouseX;
FrameY1 = FrameY2 = MouseY;
MouseStatus = POINT1;
OldMicros = Micros;
OldSecs = Secs;
/* We have the first point. Now go for the second */
break;
case POINT1:
if (DoubleClick(OldSecs, OldMicros, Secs, Micros)) {
/* Did we double-click? Then we have selected a center */
MouseStatus = CENTERFRAMING;
MidX = FrameX1;
MidY = FrameY1;
break;
}
FrameX2 = MouseX;
FrameY2 = MouseY;
/* Fall through to CENTERFRAMING */
case CENTERFRAMING:
if (FrameX1 == FrameX2 || FrameY1 == FrameY2) break;
EnableSystemGadgets(MainWindow->FirstGadget);
MouseStatus = FLASHING;
/* Point 1 should be upper left */
if (FrameX2 < FrameX1) {
/* I DO know I am reusing a variable here. Sorry! */
left=FrameX2; FrameX2=FrameX1; FrameX1=left;
}
if (FrameY2 < FrameY1) {
left=FrameY2; FrameY2=FrameY1; FrameY1=left;
}
break;
} /* End switch MouseStatus */
} /* End if Code == SELECTDOWN */
return;
} /* End if Class == MOUSEBUTTONS */
/* We are moving the mouse. Show something! */
SetDrMd(MainWindow->RPort, (ULONG) COMPLEMENT);
switch (MouseStatus) {
/* case NOTFRAMING: */
/* return; */
case NOPOINT:
FrameX1 = FrameX2 = MouseX;
FrameY1 = FrameY2 = MouseY;
/* WaitBOVP(&MandelScreen->ViewPort); */
WaitTOF();
CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
/* WaitBOVP(&MandelScreen->ViewPort); */
WaitTOF();
CrossDraw(MainWindow->RPort, FrameX1, FrameY1,
0, MainWindow->GZZWidth-1, 0, MainWindow->GZZHeight-1);
break;
case CENTERFRAMING:
FrameX1 = MouseX;
FrameY1 = MouseY;
FrameX2 = 2*MidX - FrameX1;
FrameY2 = 2*MidY - FrameY1;
skipto flashing;
case POINT1:
FrameX2 = MouseX;
FrameY2 = MouseY;
/* Deliberate Fall-Through to FLASHING */
case FLASHING:
flashing:
/* WaitBOVP(&MandelScreen->ViewPort); */
WaitTOF();
RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
/* WaitBOVP(&MandelScreen->ViewPort); */
WaitTOF();
RectDraw(MainWindow->RPort, FrameX1, FrameY1, FrameX2, FrameY2);
}
}
void InitPenTable()
{
register int i;
switch (PenTableMode) {
case MODULO:
PenTable[0] = 0;
for (i=1; i<MAXDEPTH; i++) PenTable[i] = 1 + i % (NumColors - 1);
break;
case RANGES:
PenTable[0] = 0;
for (i=1; i<MAXDEPTH; i++)
PenTable[i] = 1 + (i/RangeWidth) % (NumColors - 1);
case SELECT:
/* Don't change the table if it is user-defined */
break;
}
}
void SelectMenu(MenuNum, CheckIt)
LONG MenuNum;
bool CheckIt;
{
struct MenuItem *Item = ItemAddress(MandelMenu, MenuNum);
ClearMenuStrip(MainWindow);
if (CheckIt)
Item->Flags |= CHECKED;
else
Item->Flags &= ~CHECKED;
SetMenuStrip(MainWindow, MandelMenu);
}
void MakeMAND(mand)
struct Mand *mand;
{
int i;
mand->MandID = MAND;
mand->Size = sizeof(struct Mand);
mand->MaxDepth = MaxDepth;
mand->RangeWidth = RangeWidth;
mand->RainDist = RainbowDistance;
mand->RainRMax = RainbowRMax;
mand->RainGMax = RainbowGMax;
mand->RainBMax = RainbowBMax;
for (i=0; i < sizeof(mand->Coords); i++)
mand->Coords[i] = '\0';
sprintf(&mand->Coords[0], "%1.10g %1.10g %1.10g %1.10g",
LeftEdge, RightEdge, TopEdge, BottomEdge);
}
bool InterpretMAND(mand)
struct Mand *mand;
{
double NewLeftEdge, NewRightEdge, NewTopEdge, NewBottomEdge;
/* Perform some checks on correctness of the chunk */
if (mand->MandID != MAND || mand->Size > sizeof(struct Mand) ||
mand->MaxDepth > MAXDEPTH || mand->RangeWidth > MAXDEPTH)
return FALSE;
if (sscanf(&mand->Coords[0], "%lf %lf %lf %lf",
&NewLeftEdge, &NewRightEdge, &NewTopEdge, &NewBottomEdge) < 4)
return FALSE;
MaxDepth = mand->MaxDepth;
RangeWidth = mand->RangeWidth;
LeftEdge = NewLeftEdge;
RightEdge = NewRightEdge;
TopEdge = NewTopEdge;
BottomEdge = NewBottomEdge;
CalcCSteps();
RainbowDistance = mand->RainDist;
RainbowRMax = mand->RainRMax;
RainbowGMax = mand->RainGMax;
RainbowBMax = mand->RainBMax;
return TRUE;
}
void CalcCSteps()
{
CXStep = (double) (RightEdge - LeftEdge) / ( MainWindow->GZZWidth - 1);
CYStep = (double) (TopEdge - BottomEdge) / ( MainWindow->GZZHeight - 1);
}